﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace M3G {
    public class ShaderProgram : Object3D {
        #region Field
        VertexShader     vertexShader;
        FragmentShader   fragmentShader;
        ShaderVariable[] attributes;
        ShaderVariable[] uniforms;
        string           log;
        #endregion

        #region Method
        public ShaderProgram (VertexShader vertexShader, FragmentShader fragmentShader) {
            this.vertexShader = vertexShader;
            this.fragmentShader = fragmentShader;
            this.attributes = new ShaderVariable[0];
            this.uniforms = new ShaderVariable[0];
            this.log = "Not linked";

        }

        protected ShaderProgram (ShaderProgram shaderProgram)
            : base (shaderProgram) {
                this.vertexShader = shaderProgram.vertexShader;
                this.fragmentShader = shaderProgram.fragmentShader;
                this.attributes = (ShaderVariable[])shaderProgram.attributes.Clone ();
                this.uniforms = (ShaderVariable[])shaderProgram.uniforms.Clone ();
                this.log = (string)shaderProgram.log.Clone ();
        }

        static public ShaderProgram CreateFixedShaderProgram () {
            return null;
        }

        public int AttributeCount {
            get { return attributes.Length; }
        }

        public ShaderVariable[] Attributes {
            get { return (ShaderVariable[])attributes.Clone (); }
        }

        public int UniformCount {
            get { return uniforms.Length; }
        }

        public ShaderVariable[] Uniforms {
            get { return (ShaderVariable[])uniforms.Clone (); }
        }

        public VertexShader VertexShader {
            get { return vertexShader; }
        }

        public FragmentShader FragmentShader {
            get { return fragmentShader; }
        }

        public string InfoLog {
            get { return log; }
        }

        public override Object3D[] References {
            get {
                var q = new List<Object3D> ();
                q.AddRange (base.References);
                q.Add (vertexShader);
                q.Add (fragmentShader);
                q.RemoveAll (x => x == null);
                return q.ToArray ();
            }
        }

        internal void SetInfoLog (string log) {
            this.log = log;
        }

        internal void SetUniforms (ShaderVariable[] uniforms) {
            this.uniforms = uniforms;
        }

        internal void SetAttributes (ShaderVariable[] attributes) {
            this.attributes = attributes;
        }

        public override Object3D Duplicate () {
            return new ShaderProgram (this);
        }
        #endregion


    }
}
